﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace IFServerDLL.Model
{
    public enum MyEnumDirection
    {
        Buy,
        Sell
    }
    public enum MyEnumOpenClose
    {
        Open,
        Close,
        CloseToday,
        CloseYesterday
    }

    public enum EnumOrderStatusType : byte
    {
        /// <summary>
        /// 全部成交
        /// </summary>
        全部成交 = (byte)'0',

        /// <summary>
        /// 部分成交还在队列中
        /// </summary>
        部分成交还在队列中 = (byte)'1',

        /// <summary>
        /// 部分成交不在队列中
        /// </summary>
        部分成交不在队列中 = (byte)'2',

        /// <summary>
        /// 未成交还在队列中
        /// </summary>
        未成交还在队列中 = (byte)'3',

        /// <summary>
        /// 未成交不在队列中
        /// </summary>
        未成交不在队列中 = (byte)'4',

        /// <summary>
        /// 撤单
        /// </summary>
        撤单 = (byte)'5',

        /// <summary>
        /// 未知
        /// </summary>
        已撤单 = (byte)'a',

        /// <summary>
        /// 尚未触发
        /// </summary>
        尚未触发 = (byte)'b',

        /// <summary>
        /// 已触发
        /// </summary>
        已触发 = (byte)'c'
    }
    [DataContract]
    public class OrderBase
    {
        static int _SeqNo = 0;
        public OrderBase()
        {
            _SeqNo++;
            SeqNo = _SeqNo;
        }
        
        public OrderBase(UserOrdBase ord,DateTime marketTime)
        {
            CalcCancelID = Guid.Empty;
            CalcOrderID = ord.CalcID;
            OrdID = Guid.NewGuid();
            OrdTime = marketTime;
            StateMsg = string.Empty;
            OrderStatusType = EnumOrderStatusType.尚未触发;
            if (MyEnumOpenClose.Open==ord.OpenOrClose)
            {
                NoTradeVolume = ord.Volume;
                OrdVolume = ord.Volume;
            }
            else
            {
                NoTradeVolume = -ord.Volume;
                OrdVolume = -ord.Volume;
            }
            Instrument = ord.Instrument;
            LastTradeTime = null;
            BuyOrSell = ord.BuyOrSell;
            OpenOrClose = ord.OpenOrClose;
            Price = ord.Price;
            
            CreateTime = ord.UserCreateOrdTime;
            _SeqNo++;
            SeqNo = _SeqNo;
        }
        public bool IsOnhand()
        {
            return OrderStatusType == EnumOrderStatusType.未成交还在队列中 || OrderStatusType == EnumOrderStatusType.已触发 || OrderStatusType == EnumOrderStatusType.部分成交还在队列中;
        }
        public void UpdateState(EnumOrderStatusType type)
        {
            OrderStatusType = type;
            if (OpenOrClose == MyEnumOpenClose.Open)
            {
                if (type == EnumOrderStatusType.未成交还在队列中 || type == EnumOrderStatusType.已触发 || type == EnumOrderStatusType.部分成交还在队列中)
                {
                    FrozenCash = GlobalStatic.GetCash(Instrument, NoTradeVolume, Price);
                    FrozenCommission = GlobalStatic.GetCommiss(Instrument, NoTradeVolume, Price);
                    return;
                }
            }
            FrozenCash = 0;
            FrozenCommission = 0;
            _SeqNo++;
            SeqNo = _SeqNo;
        }
        public void UpdateTrade(int tradeVolume, DateTime marketTime)
        {
            LastTradeTime = marketTime;
            TradeVolume += tradeVolume;
            NoTradeVolume = OrdVolume - TradeVolume;
            if (OpenOrClose == MyEnumOpenClose.Open)
            {
                
                FrozenCash = GlobalStatic.GetCash(Instrument, NoTradeVolume, Price);
                FrozenCommission = GlobalStatic.GetCommiss(Instrument, NoTradeVolume, Price);

            }
            else
            {
                FrozenCash = 0;
                FrozenCommission =0;
            }
            if (NoTradeVolume == 0)
            {
                UpdateState(EnumOrderStatusType.全部成交);
            }
            else
            {
                UpdateState(EnumOrderStatusType.部分成交还在队列中);
            }
            if (OpenOrClose == MyEnumOpenClose.Open)
            {
                if (NoTradeVolume < 0)
                {
                    throw new Exception("error trade volume");
                }
            }
            else
            {
                if (NoTradeVolume > 0)
                {
                    throw new Exception("error trade volume");
                }
            }
            _SeqNo++;
            SeqNo = _SeqNo;
        }
        [DataMember]
        public Guid CalcOrderID { get; set; }
        [DataMember]
        public Guid CalcCancelID { get; set; }
        [DataMember]
        public Guid OrdID { get; set; }
        [DataMember]
        public int SeqNo { get; set; }
        [DataMember]
        public DateTime OrdTime { get; set; }
        [DataMember]
        public string StateMsg { get; set; }
        [DataMember]
        public EnumOrderStatusType OrderStatusType { get; set; }
        [DataMember]
        public int NoTradeVolume { get; set; }
        [DataMember]
        public int TradeVolume { get; set; }
        [DataMember]
        public DateTime? LastTradeTime { get; set; }
        [DataMember]
        public decimal FrozenCash { get; set; }
        [DataMember]
        public decimal FrozenCommission { get; set; }
        [DataMember]
        public string Instrument { get; set; }
        [DataMember]
        public MyEnumDirection BuyOrSell { get; set; }
        [DataMember]
        public MyEnumOpenClose OpenOrClose { get; set; }
        [DataMember]
        public decimal Price { get; set; }
        [DataMember]
        public int OrdVolume { get; set; }
        [DataMember]
        public DateTime CreateTime { get; set; }




    }
}
